#include "SceneManager.h"
#include "Scene.h"
#include "Utility/Utility.h"

CSceneManager::CSceneManager()
{
	m_SceneIDSeed = 0;	
}

CSceneManager::~CSceneManager()
{
	m_SceneIDSeed = 0;
	m_ActiveScenes.clear();

	std::map<SceneID, CScene*>::iterator it = m_SceneMap.begin();
	for (; it != m_SceneMap.end(); ++it)
	{
		CScene *pScene = it->second;
		SAFE_DELETE(pScene);
	}
	m_SceneMap.clear();
}

CScene* CSceneManager::GetSceneByID( SceneID sceneID )
{
	std::map<SceneID, CScene*>::iterator find_it = m_SceneMap.find(sceneID);
	if (find_it != m_SceneMap.end())
	{
		return find_it->second;
	}
	return NULL;
}

CScene* CSceneManager::CreateScene(const std::string& strSceneName )
{
	SceneID newSceneID = _GenerateSceneID();
	CScene* pScene = new CScene(newSceneID, strSceneName);
	DBG_ASSERT(pScene != NULL);
		
	m_SceneMap[newSceneID] = pScene;
	return pScene;
}

CScene* CSceneManager::LoadScene( const std::string& filepath )
{
	CScene* pScene = CreateScene("");
	if (pScene != NULL)
	{
		bool bRet = pScene->Load(filepath);
		DBG_ASSERT(bRet);
	}
	return pScene;
}

void CSceneManager::DestroyScene( CScene* pScene )
{
	DBG_ASSERT(pScene != NULL);

	SceneID sceneID = pScene->GetID();
	DestroyScene(sceneID);
}

void CSceneManager::DestroyScene( SceneID sceneID )
{
	std::map<SceneID, CScene*>::iterator find_it = m_SceneMap.find(sceneID);
	if (find_it != m_SceneMap.end())
	{
		DeactivateScene(sceneID);

		SAFE_DELETE(find_it->second);
		m_SceneMap.erase(find_it);
	}
}

SceneID CSceneManager::_GenerateSceneID()
{
	SceneID newSceneID = m_SceneIDSeed;
	m_SceneIDSeed++;

	return newSceneID;
}

void CSceneManager::ActivateScene( SceneID sceneID )
{
	if (GetSceneByID(sceneID) != NULL)
	{
		m_ActiveScenes.insert(sceneID);
	}
}

void CSceneManager::DeactivateScene( SceneID sceneID )
{
	if (m_ActiveScenes.count(sceneID))
	{
		m_ActiveScenes.erase(sceneID);
	}
}

bool CSceneManager::IsSceneActive(SceneID sceneID)
{
	return m_ActiveScenes.count(sceneID) > 0;
}

void CSceneManager::Update( float fTime )
{
	std::set<SceneID>::iterator sit = m_ActiveScenes.begin();
	for (; sit != m_ActiveScenes.end(); ++sit)
	{
		SceneID sceneID = *sit;
		CScene* pScene = GetSceneByID(sceneID);
		pScene->Update(fTime);
	}
}

void CSceneManager::Render()
{
	std::set<SceneID>::iterator sit = m_ActiveScenes.begin();
	for (; sit != m_ActiveScenes.end(); ++sit)
	{
		SceneID sceneID = *sit;
		CScene* pScene = GetSceneByID(sceneID);
		pScene->Render();
	}
}
